using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using hao_Common.Response.Builders;
using System.Net;

namespace hao_Common.Response.Middleware
{
    /// <summary>
    /// 全局异常处理中间件
    /// </summary>
    public class GlobalExceptionMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly ILogger<GlobalExceptionMiddleware> _logger;

        public GlobalExceptionMiddleware(RequestDelegate next, ILogger<GlobalExceptionMiddleware> logger)
        {
            _next = next;
            _logger = logger;
        }

        public async Task InvokeAsync(HttpContext context)
        {
            try
            {
                await _next(context);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "发生未处理的异常: {Message}", ex.Message);
                await HandleExceptionAsync(context, ex);
            }
        }

        private static async Task HandleExceptionAsync(HttpContext context, Exception exception)
        {
            context.Response.ContentType = "application/json";
            
            var response = exception switch
            {
                ArgumentException => ApiResponseBuilder.ValidationFail(exception.Message),
                UnauthorizedAccessException => ApiResponseBuilder.Unauthorized(exception.Message),
                KeyNotFoundException => ApiResponseBuilder.NotFound(exception.Message),
                NotImplementedException => ApiResponseBuilder.ServerError("功能尚未实现"),
                TimeoutException => ApiResponseBuilder.ServerError("请求超时"),
                _ => ApiResponseBuilder.ServerError("服务器内部错误")
            };

            // 设置请求ID
            response.RequestId = context.TraceIdentifier;

            // 设置HTTP状态码
            context.Response.StatusCode = exception switch
            {
                ArgumentException => (int)HttpStatusCode.BadRequest,
                UnauthorizedAccessException => (int)HttpStatusCode.Unauthorized,
                KeyNotFoundException => (int)HttpStatusCode.NotFound,
                NotImplementedException => (int)HttpStatusCode.NotImplemented,
                TimeoutException => (int)HttpStatusCode.RequestTimeout,
                _ => (int)HttpStatusCode.InternalServerError
            };

            var jsonResponse = JsonConvert.SerializeObject(response, Formatting.Indented);
            await context.Response.WriteAsync(jsonResponse);
        }
    }
}